/**
 * 内存数据库迁移到 MongoDB 脚本
 * 将现有的内存数据、JSON 文件数据迁移到 MongoDB
 */

import { connectMongoDB } from '../config/mongodb';
import { mongoDBService } from '../services/mongodb-service';
import * as path from 'path';
import * as fs from 'fs';

class DataMigration {
  
  /**
   * 执行完整迁移
   */
  async runMigration(): Promise<void> {
    try {
      console.log('🚀 开始数据迁移到 MongoDB...');
      
      // 1. 连接数据库
      await connectMongoDB();
      
      // 2. 迁移用户数据
      await this.migrateUsers();
      
      // 3. 迁移人脸数据
      await this.migrateFaceData();
      
      // 4. 迁移医疗告警数据（如果有的话）
      await this.migrateMedicalData();
      
      // 5. 创建示例数据
      await this.createSampleData();

      // 6. 修复 wxusers phone 索引与数据（以免 null 导致唯一索引冲突）
      await this.fixWxUsersPhoneIndex();
      
      console.log('✅ 数据迁移完成！');
      console.log('');
      console.log('📊 迁移统计:');
      await this.printMigrationStats();
      
    } catch (error) {
      console.error('❌ 数据迁移失败:', error);
      throw error;
    }
  }

  /**
   * 迁移用户数据
   */
  async migrateUsers(): Promise<void> {
    try {
      console.log('👥 开始迁移用户数据...');
      
      let migratedCount = 0;
      let skippedCount = 0;
      
      // 方法1: 尝试从内存数据库导入
      try {
        const authModule = await import('../routes/auth');
        const userDb = (authModule as any).userDb as Map<string, any>;
        
        if (userDb && userDb.size > 0) {
          console.log(`📋 发现内存用户数据: ${userDb.size} 个用户`);
          
          for (const [userId, userData] of userDb.entries()) {
            try {
              // 检查用户是否已存在
              const existingUser = await mongoDBService.getUserById(userId);
              
              if (existingUser) {
                console.log(`  - 跳过已存在用户: ${userData.username}`);
                skippedCount++;
                continue;
              }
              
              // 创建新用户
              await mongoDBService.createUser({
                userId,
                username: userData.username,
                password: userData.password, // 已经是加密的
                email: userData.email,
                role: userData.role,
                phone: userData.phone || undefined,
                createdAt: new Date(userData.created_at || Date.now()),
                hasFace: userData.has_face || false
              } as any);
              
              console.log(`  ✅ 迁移用户: ${userData.username} (${userData.email})`);
              migratedCount++;
              
            } catch (error) {
              console.error(`  ❌ 迁移用户 ${userData.username} 失败:`, error);
            }
          }
        } else {
          throw new Error('内存用户数据为空');
        }
      } catch (memoryError) {
        console.log('⚠️ 无法从内存数据库导入，尝试从导出文件导入...');
        
        // 方法2: 从导出的JSON文件导入
        try {
          const exportedUsersPath = path.join(process.cwd(), 'exported-data', 'users.json');
          
          if (fs.existsSync(exportedUsersPath)) {
            const exportedUsers = JSON.parse(fs.readFileSync(exportedUsersPath, 'utf-8'));
            console.log(`📄 发现导出用户文件: ${exportedUsers.length} 个用户`);
            
            for (const userData of exportedUsers) {
              try {
                // 检查用户是否已存在
                const existingUser = await mongoDBService.getUserById(userData.id);
                
                if (existingUser) {
                  console.log(`  - 跳过已存在用户: ${userData.username}`);
                  skippedCount++;
                  continue;
                }
                
                // 创建新用户
                await mongoDBService.createUser({
                  userId: userData.id,
                  username: userData.username,
                  password: userData.password, // 已经是加密的
                  email: userData.email,
                  role: userData.role,
                  phone: userData.phone || undefined,
                  createdAt: new Date(userData.created_at || Date.now()),
                  hasFace: userData.has_face || false
                } as any);
                
                console.log(`  ✅ 迁移用户: ${userData.username} (${userData.email})`);
                migratedCount++;
                
              } catch (error) {
                console.error(`  ❌ 迁移用户 ${userData.username} 失败:`, error);
              }
            }
          } else {
            throw new Error('导出用户文件不存在');
          }
        } catch (fileError) {
          console.log('⚠️ 无法从文件导入，创建默认用户...');
          await this.createDefaultUsers();
          return;
        }
      }
      
      console.log(`✅ 用户迁移完成: ${migratedCount} 个新用户，${skippedCount} 个跳过`);
      
    } catch (error) {
      console.error('❌ 用户数据迁移失败:', error);
      throw error;
    }
  }

  /**
   * 修复 wxusers 的 phone 索引与数据
   * - 将 phone 为 null/空串 的记录改为未设置（$unset）
   * - 删除旧的 phone 索引，重建为部分唯一索引（仅对非空手机号唯一）
   */
  async fixWxUsersPhoneIndex(): Promise<void> {
    try {
      const mongoose = (await import('mongoose')).default;
      const db = mongoose.connection.db;
      if (!db) {
        console.log('[迁移] 未连接到数据库，跳过 wxusers 索引修复');
        return;
      }
      const col = db.collection('wxusers');

      // 1) 清理数据中的 null/空串手机号
      const cleanRes1 = await col.updateMany({ phone: null }, { $unset: { phone: '' } });
      const cleanRes2 = await col.updateMany({ phone: '' }, { $unset: { phone: '' } });
      console.log(`[迁移] 清理 wxusers phone=null: ${cleanRes1.modifiedCount}, phone='' 清理: ${cleanRes2.modifiedCount}`);

      // 2) 删除旧索引（如果存在）
      const indexes = await col.indexes();
      const phoneIndex = indexes.find(i => i.name === 'phone_1');
      if (phoneIndex) {
        try {
          await col.dropIndex('phone_1');
          console.log('[迁移] 已删除旧的 wxusers.phone_1 索引');
        } catch (e) {
          console.log('[迁移] 删除旧索引失败或不存在，忽略');
        }
      }

      // 3) 重建部分唯一索引 - 修复语法问题
      await col.createIndex(
        { phone: 1 },
        { unique: true, partialFilterExpression: { phone: { $exists: true, $type: 'string' } } }
      );
      console.log('[迁移] 已重建 wxusers.phone 部分唯一索引');
    } catch (error) {
      console.error('[迁移] 修复 wxusers phone 索引失败:', error);
    }
  }

  /**
   * 迁移人脸数据
   */
  async migrateFaceData(): Promise<void> {
    try {
      console.log('👤 开始迁移人脸数据...');
      
      const faceDataPath = path.join(process.cwd(), 'face_data.json');
      
      if (!fs.existsSync(faceDataPath)) {
        console.log('⚠️ face_data.json 文件不存在，跳过人脸数据迁移');
        return;
      }
      
      const faceData = JSON.parse(fs.readFileSync(faceDataPath, 'utf-8'));
      let syncedCount = 0;
      
      for (const [username, data] of Object.entries(faceData)) {
        try {
          const faceInfo = data as { name: string; hash: string; timestamp: string };
          
          // 根据用户名查找用户
          const user = await mongoDBService.getUserByUsername(username);
          
          if (user) {
            await mongoDBService.updateUserFaceData(user.userId, {
              hash: faceInfo.hash,
              timestamp: new Date(faceInfo.timestamp)
            });
            
            console.log(`  ✅ 同步人脸数据: ${username}`);
            syncedCount++;
          } else {
            console.log(`  ⚠️ 未找到用户: ${username}，跳过人脸数据`);
          }
          
        } catch (error) {
          console.error(`  ❌ 同步人脸数据 ${username} 失败:`, error);
        }
      }
      
      console.log(`✅ 人脸数据迁移完成: ${syncedCount} 个用户`);
      
    } catch (error) {
      console.error('❌ 人脸数据迁移失败:', error);
      throw error;
    }
  }

  /**
   * 迁移医疗数据（如果项目中有的话）
   */
  async migrateMedicalData(): Promise<void> {
    try {
      console.log('🏥 开始迁移医疗数据...');
      
      // 检查是否有医疗数据文件
      const medicalDataPath = path.join(process.cwd(), '../h5/src/app/(main)/dashboard/medical-data.json');
      
      if (fs.existsSync(medicalDataPath)) {
        const medicalData = JSON.parse(fs.readFileSync(medicalDataPath, 'utf-8'));
        let alertCount = 0;
        
        for (const item of medicalData) {
          try {
            // 使用upsert逻辑，避免重复键问题
            const { MedicalAlert } = await import('../models/mongodb-schemas');
            
            await MedicalAlert.findOneAndUpdate(
              { alertId: item.id },
              {
                alertId: item.id,
                type: item.type,
                title: item.title,
                location: item.location,
                status: item.status,
                priority: item.priority,
                description: item.description,
                assignee: item.assignee,
                impact: item.impact,
                estimatedResolution: item.estimatedResolution,
                createdAt: new Date(item.timestamp),
                updatedAt: new Date()
              },
              { 
                upsert: true, 
                new: true 
              }
            );
            
            console.log(`  ✅ 迁移医疗告警: ${item.title}`);
            alertCount++;
            
          } catch (error) {
            console.error(`  ❌ 迁移医疗告警失败:`, error);
          }
        }
        
        console.log(`✅ 医疗数据迁移完成: ${alertCount} 个告警`);
      } else {
        console.log('⚠️ 未发现医疗数据文件，跳过');
      }
      
    } catch (error) {
      console.error('❌ 医疗数据迁移失败:', error);
      // 不抛出错误，允许迁移继续
    }
  }

  /**
   * 创建默认用户（如果内存中没有用户）
   */
  async createDefaultUsers(): Promise<void> {
    const bcrypt = await import('bcrypt');
    
    const defaultUsers = [
      {
        userId: 'user_admin_001',
        username: 'admin',
        email: 'admin@hospital.com',
        password: await bcrypt.hash('admin123', 10),
        role: 'admin',
        phone: '13800000001'
      },
      {
        userId: 'user_test_002', 
        username: 'testuser',
        email: 'test@hospital.com',
        password: await bcrypt.hash('test123', 10),
        role: 'user',
        phone: '13800000002'
      },
      {
        userId: 'user_doctor_003',
        username: 'doctor',
        email: 'doctor@hospital.com', 
        password: await bcrypt.hash('doctor123', 10),
        role: 'user',
        phone: '13800000003'
      }
    ];
    
    for (const userData of defaultUsers) {
      try {
        const existingUser = await mongoDBService.getUserByUsername(userData.username);
        if (!existingUser) {
          await mongoDBService.createUser(userData as any);
          console.log(`  ✅ 创建默认用户: ${userData.username}`);
        }
      } catch (error) {
        console.error(`  ❌ 创建默认用户 ${userData.username} 失败:`, error);
      }
    }
  }

  /**
   * 创建示例数据
   */
  async createSampleData(): Promise<void> {
    try {
      console.log('📋 创建示例数据...');
      
      // 检查是否已有数据
      const existingAlerts = await mongoDBService.getMedicalAlerts({ limit: 1 });
      const existingEquipment = await mongoDBService.getMedicalEquipment({ limit: 1 });
      
      // 创建医疗告警示例
      if (existingAlerts.length === 0) {
        const alertsToCreate = [
          {
            type: 'device',
            title: 'CT设备需要维护',
            location: '影像科A区',
            status: 'active',
            priority: 'medium',
            description: '设备连续运行18小时，温度传感器异常，需要立即维护',
            assignee: '医疗设备科',
            impact: 'CT检查延迟，需调配其他设备',
            estimatedResolution: '2小时'
          },
          {
            type: 'alert',
            title: '急诊科患者聚集告警',
            location: '急诊科等候区',
            status: 'active',
            priority: 'high',
            description: '等候区患者数量超出设计容量，当前密度3.2人/㎡，超出安全标准',
            assignee: '急诊科值班医生',
            impact: '患者等待时间增加，满意度下降',
            estimatedResolution: '15分钟'
          },
          {
            type: 'maintenance',
            title: '手术室03环境异常',
            location: '手术室03',
            status: 'resolved',
            priority: 'high',
            description: '温度28.5℃，湿度72%，超出手术环境标准要求',
            assignee: '手术室护士长',
            impact: '手术暂停，患者安全风险',
            estimatedResolution: '已解决'
          }
        ];
        
        for (const alertData of alertsToCreate) {
          await mongoDBService.createMedicalAlert(alertData as any);
          console.log(`  ✅ 创建医疗告警: ${alertData.title}`);
        }
      }
      
      // 创建医疗设备示例
      if (existingEquipment.length === 0) {
        const equipmentToCreate = [
          {
            name: 'CT-01',
            type: 'ct',
            location: '影像科A区',
            status: 'active',
            description: '64排螺旋CT',
            specifications: '64排，层厚0.5mm',
            manufacturer: 'GE Healthcare'
          },
          {
            name: 'MRI-01',
            type: 'mri',
            location: '影像科B区',
            status: 'active',
            description: '3.0T磁共振成像设备',
            specifications: '3.0T，32通道',
            manufacturer: 'Siemens'
          },
          {
            name: 'X光机-02',
            type: 'xray',
            location: 'L2放射科',
            status: 'active',
            description: 'DR数字化X光机',
            specifications: '14×17英寸探测器',
            manufacturer: 'Philips'
          },
          {
            name: '呼吸机-ICU-01',
            type: 'ventilator',
            location: 'ICU病房',
            status: 'active',
            description: '有创无创一体化呼吸机',
            specifications: '支持多种通气模式',
            manufacturer: 'Dräger'
          }
        ];
        
        for (const equipmentData of equipmentToCreate) {
          await mongoDBService.createMedicalEquipment(equipmentData as any);
          console.log(`  ✅ 创建医疗设备: ${equipmentData.name}`);
        }
      }
      
      console.log('✅ 示例数据创建完成');
      
    } catch (error) {
      console.error('❌ 创建示例数据失败:', error);
    }
  }

  /**
   * 打印迁移统计信息
   */
  async printMigrationStats(): Promise<void> {
    try {
      const userCount = (await mongoDBService.getAllUsers()).length;
      const alertCount = (await mongoDBService.getMedicalAlerts({ limit: 1000 })).length;
      const equipmentCount = (await mongoDBService.getMedicalEquipment({ limit: 1000 })).length;
      const ocrCount = (await mongoDBService.getOCRHistory('', 1000)).length;
      
      console.log(`- 用户数量: ${userCount}`);
      console.log(`- 医疗告警: ${alertCount}`);
      console.log(`- 医疗设备: ${equipmentCount}`);
      console.log(`- OCR记录: ${ocrCount}`);
      
      // 统计人脸数据
      const usersWithFace = (await mongoDBService.getAllUsers()).filter(user => user.hasFace);
      console.log(`- 有人脸数据的用户: ${usersWithFace.length}`);
      
    } catch (error) {
      console.error('获取统计信息失败:', error);
    }
  }

  /**
   * 验证迁移结果
   */
  async validateMigration(): Promise<void> {
    try {
      console.log('🔍 验证迁移结果...');
      
      // 验证用户数据
      const users = await mongoDBService.getAllUsers();
      console.log(`✅ 用户验证: 共 ${users.length} 个用户`);
      
      for (const user of users.slice(0, 3)) { // 只显示前3个
        console.log(`  - ${user.username} (${user.email}) - 角色: ${user.role}`);
      }
      
      // 验证人脸数据
      const usersWithFace = users.filter(user => user.hasFace);
      console.log(`✅ 人脸数据验证: ${usersWithFace.length} 个用户有人脸数据`);
      
      // 验证告警数据
      const alerts = await mongoDBService.getMedicalAlerts({ limit: 10 });
      console.log(`✅ 告警数据验证: 共 ${alerts.length} 条告警`);
      
      console.log('✅ 迁移验证完成');
      
    } catch (error) {
      console.error('❌ 迁移验证失败:', error);
    }
  }
}

// 执行迁移的主函数
async function runMigration() {
  const migration = new DataMigration();
  
  try {
    await migration.runMigration();
    await migration.validateMigration();
    
    console.log('');
    console.log('🎉 数据迁移成功完成！');
    console.log('💡 提示: 可以通过以下API查看迁移结果:');
    console.log('  - GET /v1/mongodb/users');
    console.log('  - GET /v1/mongodb/alerts');
    console.log('  - GET /v1/mongodb/connection');
    
    process.exit(0);
  } catch (error) {
    console.error('💥 数据迁移失败:', error);
    process.exit(1);
  }
}

// 如果直接运行此脚本，则执行迁移
if (require.main === module) {
  runMigration();
}

export { DataMigration, runMigration };